package com.lier.gulimall.member.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.client.naming.net.HttpClient;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.lier.common.exception.EmailExistException;
import com.lier.common.exception.RequestException;
import com.lier.common.exception.UsernameExistException;
import com.lier.common.vo.GiteeTokenVo;
import com.lier.common.vo.GiteeUser;
import com.lier.common.vo.MemberLoginVo;
import com.lier.common.vo.MemberRegisterVo;
import com.lier.gulimall.member.dao.MemberLevelDao;
import com.lier.gulimall.member.entity.MemberLevelEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Handler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lier.common.utils.PageUtils;
import com.lier.common.utils.Query;

import com.lier.gulimall.member.dao.MemberDao;
import com.lier.gulimall.member.entity.MemberEntity;
import com.lier.gulimall.member.service.MemberService;


@Service("memberService")
public class MemberServiceImpl extends ServiceImpl<MemberDao, MemberEntity> implements MemberService {


    @Autowired
    private MemberLevelDao memberLevelDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<MemberEntity> page = this.page(
                new Query<MemberEntity>().getPage(params),
                new QueryWrapper<MemberEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public void register(MemberRegisterVo MemberRegisterVo) {
        MemberEntity memberEntity = new MemberEntity();

        // 检测用户名称和email唯一性
        checkUsernameUnique(MemberRegisterVo.getUsername());
        checkEmailUnique(MemberRegisterVo.getEmail());

        memberEntity.setEmail(MemberRegisterVo.getEmail());
        memberEntity.setUsername(MemberRegisterVo.getUsername());

        // 密码加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String saltPassword = bCryptPasswordEncoder.encode(MemberRegisterVo.getPassword());
        memberEntity.setPassword(saltPassword);

        // 会员等级
        MemberLevelEntity memberLevelEntity = memberLevelDao.getDefaultLevel();
        memberEntity.setLevelId(memberLevelEntity.getId());

        baseMapper.insert(memberEntity);
    }

    @Override
    public void checkEmailUnique(String email) throws EmailExistException {
        Integer countOfEmail = baseMapper.selectCount(new LambdaQueryWrapper<MemberEntity>()
                .eq(MemberEntity::getEmail, email));

        if(countOfEmail > 0){
            throw new EmailExistException();
        }

    }

    @Override
    public void checkUsernameUnique(String username) throws UsernameExistException {
        Integer countOfUsername = baseMapper.selectCount(new LambdaQueryWrapper<MemberEntity>()
                .eq(MemberEntity::getUsername, username));

        if(countOfUsername > 0 ){
            throw new UsernameExistException();
        }
    }

    @Override
    public MemberEntity login(MemberLoginVo memberLoginVo) {

        MemberEntity memberEntity = baseMapper.selectOne(new LambdaQueryWrapper<MemberEntity>()
                .eq(MemberEntity::getEmail, memberLoginVo.getLoginacct())
                .or().eq(MemberEntity::getMobile, memberLoginVo.getLoginacct())
                .or().eq(MemberEntity::getUsername, memberLoginVo.getLoginacct()));

        if(memberEntity == null){
            return null;
        }

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        boolean matches = bCryptPasswordEncoder.matches(memberLoginVo.getPassword(), memberEntity.getPassword());
        if(!matches){
            return null;
        }else {
            return memberEntity;
        }
    }

    @Override
    public MemberEntity giteeLogin(GiteeTokenVo giteeTokenVo) throws RequestException {

        Map<String, String> paramsValue = new HashMap<>();

        // 获取当前登录的Gitee登录的社交账号信息
        paramsValue.put("access_token", giteeTokenVo.getAccessToken());
        HttpClient.HttpResult result = HttpClient.request("https://gitee.com/api/v5/user",
                null, paramsValue, "UTF-8", "GET");

        if(result.code == 200){

            String json = result.content;
            GiteeUser giteeUser = JSONObject.parseObject(json, GiteeUser.class);


            // 判定当前用户是否已经在当前系统中注册过
            MemberEntity memberEntity = baseMapper.selectOne(new LambdaQueryWrapper<MemberEntity>()
                    .eq(MemberEntity::getSocialUid, giteeUser.getId()));

            MemberEntity member = new MemberEntity();
            if(memberEntity != null){
                // 已经注册, 返回注册信息
                member.setId(memberEntity.getId());
                member.setUsername(giteeUser.getName());
                member.setAccessToken(giteeTokenVo.getAccessToken());
                long expire = System.currentTimeMillis() + giteeTokenVo.getExpiresIn() * 1000L;
                member.setExpiresIn(String.valueOf(expire));

                baseMapper.updateById(member);

                memberEntity.setAccessToken(giteeTokenVo.getAccessToken());
                memberEntity.setExpiresIn(String.valueOf(expire));
                memberEntity.setSocialUid(giteeUser.getId());

                return memberEntity;
            }else {

                // 未注册过, 生成一个账户绑定该登录的社交账号

                member.setNickname(giteeUser.getName());
                member.setHeader(giteeUser.getAvatarUrl());
                member.setCreateTime(new Date());

                member.setSocialUid(giteeUser.getId());
                member.setAccessToken(giteeTokenVo.getAccessToken());
                long expire = System.currentTimeMillis() + giteeTokenVo.getExpiresIn() * 1000L;
                member.setExpiresIn(String.valueOf(expire));

                baseMapper.insert(member);
                return member;
            }

        }else {
            throw new RequestException("请求获取GITEE用户信息异常");
        }
    }

}
